package com.gitee.fastmybatis.core.mapper;

import java.util.Objects;
import java.util.function.Function;

/**
 * 具备CRUD的mapper
 *
 * @param <E> 实体类，如：Student
 * @author tanghc
 */
public interface BaseMapper<E> extends LambdaSearchMapper<E>, EditMapper<E> {

    /**
     * 保存或修改，当数据库存在记录执行UPDATE，否则执行INSERT
     *
     * @param entity 实体类
     * @return 受影响行数
     */
    default int saveOrUpdate(E entity) {
        return this.saveOrUpdate(entity, this::checkExist);
    }

    /**
     * 保存或修改，当数据库存在记录执行UPDATE，否则执行INSERT
     *
     * @param entity       实体类
     * @param existChecker 检查是否存在，存在返回true，将执行UPDATE；不存在返回false，将执行INSERT
     * @return 受影响行数
     */
    default int saveOrUpdate(E entity, Function<E, Boolean> existChecker) {
        Objects.requireNonNull(entity, "entity can not null");
        Objects.requireNonNull(existChecker, "existChecker can not null");
        if (existChecker.apply(entity)) {
            return this.update(entity);
        } else {
            return this.save(entity);
        }
    }

    /**
     * 保存或修改，忽略null字段，当数据库存在记录执行UPDATE，否则执行INSERT
     *
     * @param entity 实体类
     * @return 受影响行数
     */
    default int saveOrUpdateIgnoreNull(E entity) {
        return this.saveOrUpdateIgnoreNull(entity, this::checkExist);
    }

    /**
     * 保存或修改，忽略null字段，当数据库存在记录执行UPDATE，否则执行INSERT
     *
     * @param entity       实体类
     * @param existChecker 检查是否存在，存在返回true，将执行UPDATE；不存在返回false，将执行INSERT
     * @return 受影响行数
     */
    default int saveOrUpdateIgnoreNull(E entity, Function<E, Boolean> existChecker) {
        Objects.requireNonNull(entity, "entity can not null");
        Objects.requireNonNull(existChecker, "existChecker can not null");
        if (existChecker.apply(entity)) {
            return this.updateIgnoreNull(entity);
        } else {
            return this.saveIgnoreNull(entity);
        }
    }

}
